package yxk.wtc.wtp.opplugin;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.orm.util.CollectionUtils;
import kd.hr.hbp.common.constants.HRBaseConstants;
import kd.hr.hbp.common.util.HRDateTimeUtils;
import kd.hr.hbp.common.util.HRStringUtils;
import kd.hr.hbp.opplugin.validator.HRDataBaseValidator;
import kd.wtc.wtbs.business.util.WTCDynamicObjectUtils;
import kd.wtc.wtbs.business.web.attperiod.PerAttPeriodQueryServiceImpl;
import kd.wtc.wtbs.business.web.wtte.sysparam.AttRecordParamService;
import kd.wtc.wtbs.common.constants.AttConstants;
import kd.wtc.wtbs.common.constants.WTCCommonConstants;
import kd.wtc.wtbs.common.constants.WTCHisConstants;
import kd.wtc.wtbs.common.enums.file.AttStatusEnum;
import kd.wtc.wtbs.common.model.period.PerAttPeriod;
import kd.wtc.wtbs.common.model.period.PerAttPeriodQueryParam;
import kd.wtc.wtbs.common.util.WTCDateUtils;
import kd.wtc.wtbs.wtte.common.model.AttRecordParam;
import kd.wtc.wtp.business.attfile.AttFileHelper;
import kd.wtc.wtp.business.attstateinfo.AttStateInfoService;
import kd.wtc.wtp.common.constants.AttFileConstants;
import kd.wtc.wtp.common.model.attstateinfo.AttStateInfoBO;
import kd.wtc.wtp.constants.WTPProjConstants;

import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 考勤档案修改临时扩展校验插件
 *
 * @author rd_nengkang_hu
 * @since 2023-10-30
 */
public class AttFileBaseModifyExpandValidator extends HRDataBaseValidator {
    @Override
    public void validate() {
        super.validate();
        ExtendedDataEntity[] dataEntities = getDataEntities();
        ExtendedDataEntity dataEntity = dataEntities[0];
        DynamicObject file = dataEntity.getDataEntity();
        String dataMsg = checkModifyFile(file);
        if (HRStringUtils.isNotEmpty(dataMsg)) {
            this.addFatalErrorMessage(dataEntity, dataMsg);
        }
    }

    private String checkModifyFile(DynamicObject dataEntity) {

        // 生效日期校验
        String msg = AttFileHelper.checkFileStartDate(dataEntity);
        if (HRStringUtils.isNotEmpty(msg)) {
            return msg;
        }
        Long fileBoid = dataEntity.getLong(WTCCommonConstants.BOID);
        // 获取封存信息
        List<AttStateInfoBO> attStateInfoBOS = AttStateInfoService.getInstance().queryAttStateInfoByBoid(Lists.newArrayList(fileBoid));
        Map<Long, Date> storageMap = attStateInfoBOS.stream().filter(arg -> arg.getLockTo() != null).collect(Collectors.toMap(AttStateInfoBO::getFileBoid, AttStateInfoBO::getLockTo, (a, b) -> a));
        Date storageDate = storageMap.get(fileBoid);
        // 如果是停止考勤，需要校验锁定的日期的人员考勤期间和档案开始日期不存在交集
        if (AttStatusEnum.ATT_STOP.getCode().equals(dataEntity.getString(AttFileConstants.ATT_TAG_STATUS)) && storageDate != null) {
            PerAttPeriodQueryParam perAttPeriodQueryParam = new PerAttPeriodQueryParam();
            perAttPeriodQueryParam.setAttFileBoIdSet(Sets.newHashSet(fileBoid));
            perAttPeriodQueryParam.setStartDate(storageDate);
            perAttPeriodQueryParam.setEndDate(storageDate);
            List<PerAttPeriod> perAttPeriodList = PerAttPeriodQueryServiceImpl.getInstance().queryPerAttPeriodEntity(perAttPeriodQueryParam);
            if (!CollectionUtils.isEmpty(perAttPeriodList)) {
                PerAttPeriod perAttPeriod = perAttPeriodList.get(0);
                Date fileBseDate = WTCDateUtils.addDays(dataEntity.getDate(WTCHisConstants.EFF_START_DATE), -1);
                if (fileBseDate.compareTo(perAttPeriod.getPerAttBeginDate()) >= 0 && fileBseDate.before(perAttPeriod.getPerAttEndDate())) {
                    return ResManager.loadKDString("停止考勤日期所在人员考勤期间存在锁定状态，请先解锁后操作。", "AttFileHelper_23", WTPProjConstants.WTC_WTP_BUSINESS);
                }
            }

        }
        if (storageDate != null && !dataEntity.getDate(WTCHisConstants.EFF_START_DATE).after(storageDate)) {
            return String.format(Locale.ROOT, ResManager.loadKDString("生效日期只能晚于该人员的已锁定至%s。", "AttFileHelper_2", WTPProjConstants.WTC_WTP_BUSINESS), HRDateTimeUtils.format(storageDate, WTCCommonConstants.DEF_DATE_FORMAT));
        }
        AttRecordParam attRecordParam = AttRecordParamService.getAttRecordParam(WTCDynamicObjectUtils.getBaseDataId(dataEntity, AttConstants.ORG));
        if (attRecordParam != null && attRecordParam.isAttefile()) {
            // 获取冻结信息
            Map<Long, AttStateInfoBO> frozeAllInfoMap = attStateInfoBOS.stream().collect(Collectors.toMap(AttStateInfoBO::getFileBoid, Function.identity(), (oldValue, newValue) -> oldValue));
            AttStateInfoBO attStateInfoBO = frozeAllInfoMap.get(fileBoid);
            if (attStateInfoBO == null) {
                return StringUtils.EMPTY;
            }
            Date frozenStartDate = attStateInfoBO.getFrozenStartDate();
            Date frozenEndDate = attStateInfoBO.getFronzenEnDate();
            if (checkFrozenDate(frozenStartDate, frozenEndDate, dataEntity)) {
                return String.format(ResManager.loadKDString("已冻结的日期范围内不允许编辑档案信息，已冻结范围：%1$s至%2$S。", "AttFileHelper_19", WTPProjConstants.WTC_WTP_BUSINESS), HRDateTimeUtils.format(frozenStartDate, WTCCommonConstants.DEF_DATE_FORMAT), HRDateTimeUtils.format(frozenEndDate, WTCCommonConstants.DEF_DATE_FORMAT));
            }
        }

        return StringUtils.EMPTY;
    }


    private boolean checkFrozenDate(Date frozenStartDate, Date frozenEndDate, DynamicObject dataEntity) {
        if (frozenStartDate == null || frozenEndDate == null) {
            return false;
        }
        Date modifyTime = dataEntity.getDate(WTCHisConstants.EFF_START_DATE);
        Date endDate = dataEntity.getDate(WTCHisConstants.EFF_END_DATE);
        if (frozenStartDate.compareTo(modifyTime) <= HRBaseConstants.INT_ZERO && frozenEndDate.compareTo(modifyTime) >= HRBaseConstants.INT_ZERO) {
            return true;
        }
        boolean check = (endDate == null || endDate.compareTo(frozenEndDate) >= HRBaseConstants.INT_ZERO) && modifyTime.compareTo(frozenStartDate) <= HRBaseConstants.INT_ZERO;
        if (check) {
            return true;
        }
        return endDate != null && frozenStartDate.compareTo(endDate) <= HRBaseConstants.INT_ZERO && frozenEndDate.compareTo(endDate) >= HRBaseConstants.INT_ZERO;
    }
}
